package com.dreamcode.anfeedreader.collectors;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.dreamcode.anfeedreader.database.DbHelper;
import com.dreamcode.anfeedreader.modelClass.Categories;
import com.dreamcode.anfeedreader.modelClass.Feed;
import com.dreamcode.anfeedreader.modelClass.FeedItem;

public class FeedsDAOimpl implements FeedsDAO {

	private static FeedsDAOimpl feedsDAOimpl = null;
	private Categories categories = null;
	private Feed feed = null;
	private ItemObject itemObject = null;
	private DbHelper dbHelper = null;
	private static final String MARKED_FEED_ITEM_STATUS = "2";

	public static FeedsDAOimpl getInstance() {
		if (feedsDAOimpl == null) {
			feedsDAOimpl = new FeedsDAOimpl();
		}
		return feedsDAOimpl;
	}

	@Override
	public List<Categories> getAllFeedCategories(Context ctx) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		List<Categories> categoriesList = new LinkedList<Categories>();
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_CATEGORIES, null,
				null, null, null, null, null);
		if (c.moveToFirst()) {

			do {
				categories = new Categories();
				categories.setGroupId(c.getInt(c.getColumnIndex("_id")));
				categories.setGroupName(c.getString(c
						.getColumnIndex("category")));
				categoriesList.add(categories);
			} while (c.moveToNext());

		}
		c.close();
		//dbHelper.close(dbHelper.getDb());
		return categoriesList;
	}

	@Override
	public void insertCategory(Context ctx, String name) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		contentValues.put("category", name);
		dbHelper.getDb().insert(dbHelper.DB_TABLE_CATEGORIES, null,
				contentValues);
		//dbHelper.close(dbHelper.getDb());
	}

	@Override
	public void insertNewFeed(Context ctx, List<Object> values) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		contentValues.put("feedname", (String)values.get(0));
		contentValues.put("feedurl", (String)values.get(1));
		contentValues.put("favicon", (String)values.get(2));
		contentValues.put("category", (String)values.get(3));
		dbHelper.getDb().insert(dbHelper.DB_TABLE_FEED, null, contentValues);
		//dbHelper.close(dbHelper.getDb());
	}

	@Override
	public List<Feed> getAllFeeds(Context ctx) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		List<Feed> feedList = new LinkedList<Feed>();
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEED, null, null,
				null, null, null, "_id DESC");
		if (c.moveToFirst()) {

			do {
				feed = new Feed();
				feed.setUrl(c.getString(c.getColumnIndex("feedurl")));
				feed.setId(c.getInt(c.getColumnIndex("_id")));
				feedList.add(feed);
			} while (c.moveToNext());

		}
		c.close();
		//dbHelper.close(dbHelper.getDb());
		return feedList;
	}

	@Override
	public List<ItemObject> getItemObjectsByGroup(Context ctx) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		List<ItemObject> itemObjectsList = new LinkedList<ItemObject>();
		List<Categories> categoriesList = feedsDAOimpl
				.getAllFeedCategories(ctx);
		for (int j = 0; j < categoriesList.size(); j++) {
			categories = categoriesList.get(j);
			itemObject = new ItemObject();
			itemObject.setId(categories.getGroupId());
			itemObject.setItemName(categories.getGroupName());
			itemObject.setType("label");
			itemObjectsList.add(itemObject);
			Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEED, null,
					"category=" + (categoriesList.get(j)).getGroupId(), null,
					null, null, null);
			if (c.moveToFirst()) {
				do {
					itemObject = new ItemObject();
					itemObject.setId(c.getInt(c.getColumnIndex("_id")));
					itemObject.setItemName(c.getString(c
							.getColumnIndex("feedname")));
					itemObject.setItemUrl(c.getString(c
							.getColumnIndex("feedurl")));
					itemObject.setFavIconData(c.getBlob(c.getColumnIndex("favicon")));
					itemObject.setType("feed");
					itemObjectsList.add(itemObject);
				} while (c.moveToNext());

			}
			c.close();
		}
		//dbHelper.close(dbHelper.getDb());
		return itemObjectsList;
	}

	@Override
	public List<ItemObject> getItemObjects(Context ctx) {

		return null;
	}

	@Override
	public List<FeedItem> getAllFeedItemsFromDB(Context ctx, int id) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		List<FeedItem> feedItems = new LinkedList<FeedItem>();
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"feed_id=" + id, null, null, null, "_id DESC");
		FeedItem feedItem = null;
		if (c != null) {
			c.moveToFirst();

			while (c.moveToNext()) {
				feedItem = new FeedItem();
				feedItem.setId(c.getInt(c.getColumnIndex("_id")));
				feedItem.setTitle(c.getString(c.getColumnIndex("title")));
				feedItem.setDescription(c.getString(c.getColumnIndex("body")));
				feedItem.setLink(c.getString(c.getColumnIndex("url")));
				feedItem.setPubDate(c.getString(c.getColumnIndex("pubdate")));
				feedItem.setStatus(c.getString(c.getColumnIndex("status")));
				feedItems.add(feedItem);
			}

		}
		c.close();
		//dbHelper.close(dbHelper.getDb());
		return feedItems;
	}

	@Override
	public FeedItem getFeedItemFromDB(Context ctx, int id) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"_id=" + id, null, null, null, null);
		FeedItem feedItem = null;
		if (c != null) {
			c.moveToFirst();
			feedItem = new FeedItem();
			feedItem.setId(c.getInt(c.getColumnIndex("_id")));
			feedItem.setTitle(c.getString(c.getColumnIndex("title")));
			feedItem.setDescription(c.getString(c.getColumnIndex("body")));
			feedItem.setLink(c.getString(c.getColumnIndex("url")));
			feedItem.setPubDate(c.getString(c.getColumnIndex("pubdate")));
		}
		c.close();
		//dbHelper.close(dbHelper.getDb());
		return feedItem;
	}

	@Override
	public void insertFeedItems(Context ctx, FeedItem values) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		ContentValues contentValues2 = new ContentValues();
		contentValues.put("feed_id", values.getFeed_id());
		contentValues.put("title", values.getTitle());
		contentValues.put("body", values.getDescription());
		contentValues.put("url", values.getLink());
		contentValues.put("pubdate", values.getPubDate());
		contentValues.put("md5hash", values.getMd5hash());
		contentValues.put("status", values.getStatus());

		contentValues2.put("md5hash", values.getMd5hash());
		contentValues2.put("title", values.getTitle());
		contentValues2.put("body", values.getDescription());

		dbHelper.getDb()
				.insert(dbHelper.DB_TABLE_FEEDITEM, null, contentValues);
		dbHelper.getDb().insert(dbHelper.DB_TABLE_SEARCHFEEDITEM, null,
				contentValues2);
		//dbHelper.close(dbHelper.getDb());

	}

	@Override
	public String getMd5Hash(String input) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] messageDigest = md.digest(input.getBytes());
			BigInteger number = new BigInteger(1, messageDigest);
			String md5 = number.toString(16);
			while (md5.length() < 32)
				md5 = "0" + md5;
			return md5;
		} catch (NoSuchAlgorithmException e) {
			Log.e("MD5", e.getMessage());
			return null;
		}
	}

	@Override
	public boolean checkItemExistence(Context ctx, FeedItem values) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		boolean itemExist = false;
		String md5Hash = getMd5Hash(values.getLink());
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"md5hash='" + md5Hash + "'", null, null, null, null);
		c.moveToFirst();
		if(c.getCount() > 0){
			itemExist = true;            
		}
		c.close();
        //dbHelper.close(dbHelper.getDb());
        return itemExist;
	}

	@Override
	public boolean checkFeedExistence(Context ctx, int id) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		boolean feedExist = false;
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"feed_id=" + id, null, null, null, null);
		c.moveToFirst();
		if(c.getCount() > 0){
			feedExist = true;
		}
		c.close();
        //dbHelper.close(dbHelper.getDb());
		return feedExist;
	}

	@Override
	public void deleteFeed(Context ctx, int id) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		dbHelper.getDb().delete(dbHelper.DB_TABLE_FEED, "_id=" + id, null);
		dbHelper.getDb().delete(dbHelper.DB_TABLE_FEEDITEM, "feed_id=" + id,
				null);
		//dbHelper.close(dbHelper.getDb());
	}

	@Override
	public Feed getFeed(Context ctx, int id) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEED, null,
				"_id=" + id, null, null, null, null);
		Feed feed = null;
		if (c != null) {
			c.moveToFirst();
			feed = new Feed();
			feed.setId(c.getInt(c.getColumnIndex("_id")));
			feed.setTitle(c.getString(c.getColumnIndex("feedname")));
			feed.setUrl(c.getString(c.getColumnIndex("feedurl")));
			c.close();
	        //dbHelper.close(dbHelper.getDb());
			return feed;
		} else {
			c.close();
	        //dbHelper.close(dbHelper.getDb());
			return null;
		}
	}

	@Override
	public void updateEditedFeed(Context ctx, List<Object> values) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		contentValues.put("feedname", (String)values.get(0));
		contentValues.put("feedurl", (String)values.get(1));
		contentValues.put("category", (String)values.get(2));
		dbHelper.getDb().update(dbHelper.DB_TABLE_FEED, contentValues,
				"_id=" + values.get(3), null);		
        //dbHelper.close(dbHelper.getDb());
	}

	@Override
	public FeedItem getFeedItemDetail(Context ctx, int feedItemId) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"_id=" + feedItemId, null, null, null, null);
		FeedItem feedItem = null;
		if (c != null) {
			c.moveToFirst();
			feedItem = new FeedItem();
			feedItem.setId(c.getInt(c.getColumnIndex("_id")));
			feedItem.setTitle(c.getString(c.getColumnIndex("title")));
			feedItem.setDescription(c.getString(c.getColumnIndex("body")));
			feedItem.setLink(c.getString(c.getColumnIndex("url")));
			feedItem.setPubDate(c.getString(c.getColumnIndex("pubdate")));
			feedItem.setStatus(c.getString(c.getColumnIndex("status")));
			c.close();
	        //dbHelper.close(dbHelper.getDb());
			return feedItem;
		} else {
			c.close();
	        //dbHelper.close(dbHelper.getDb());
			return null;
		}
	}

	@Override
	public List<ItemObject> getAllNoneFeeds(Context ctx,
			List<ItemObject> itemObjectsList) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		itemObject = new ItemObject();
		itemObject.setId(0);
		itemObject.setItemName("Other");
		itemObject.setType("label");
		itemObjectsList.add(itemObject);
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEED, null,
				"category=0", null, null, null, null);
		if (c.moveToFirst()) {
			do {
				itemObject = new ItemObject();
				itemObject.setId(c.getInt(c.getColumnIndex("_id")));
				itemObject.setItemName(c
						.getString(c.getColumnIndex("feedname")));
				itemObject.setItemUrl(c.getString(c.getColumnIndex("feedurl")));
				itemObject.setType("feed");
				itemObjectsList.add(itemObject);
			} while (c.moveToNext());

		}
		c.close();
        //dbHelper.close(dbHelper.getDb());
		return itemObjectsList;
	}

	@Override
	public void updateFeedItem(Context ctx, List<String> values) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		contentValues.put("status", values.get(1));
		dbHelper.getDb().update(dbHelper.DB_TABLE_FEEDITEM, contentValues,
				"_id=" + values.get(0), null);		
        //dbHelper.close(dbHelper.getDb());
	}

	@Override
	public List<FeedItem> getAllMarkedFeedItemsFromDB(Context ctx) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
				"status=" + MARKED_FEED_ITEM_STATUS, null, null, null, null);
		List<FeedItem> markedFeedItems = new LinkedList<FeedItem>();
		FeedItem feedItem = null;
		if (c.moveToFirst()) {
			do {

				feedItem = new FeedItem();
				feedItem.setId(c.getInt(c.getColumnIndex("_id")));
				feedItem.setTitle(c.getString(c.getColumnIndex("title")));
				feedItem.setDescription(c.getString(c.getColumnIndex("body")));
				feedItem.setLink(c.getString(c.getColumnIndex("url")));
				markedFeedItems.add(feedItem);
			} while (c.moveToNext());

		}
		c.close();
        //dbHelper.close(dbHelper.getDb());
		return markedFeedItems;
	}

	@Override
	public void changeStatusToMarked(Context ctx, int feedItemId) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		ContentValues contentValues = new ContentValues();
		contentValues.put("status", MARKED_FEED_ITEM_STATUS);
		dbHelper.getDb().update(dbHelper.DB_TABLE_FEEDITEM, contentValues,
				"_id=" + feedItemId, null);		
        //dbHelper.close(dbHelper.getDb());
	}

	@Override
	public List<FeedItem> search(Context ctx, String query) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		//dbHelper = new DbHelper(ctx.getApplicationContext());
		List<FeedItem> result = new ArrayList<FeedItem>();
		FeedItem feeditem = null;
		SQLiteDatabase db = dbHelper.getDb();
		final Cursor cursor = db.query(dbHelper.DB_TABLE_SEARCHFEEDITEM,
				new String[] { "md5hash", "title" }, "body" + " MATCH ?",
				new String[] { query }, null, null, null);
		if (cursor.moveToFirst()) {
			do {
				feeditem = new FeedItem();
				feeditem.setTitle(cursor.getString(cursor.getColumnIndexOrThrow("title")));
				feeditem.setMd5hash(cursor.getString(cursor.getColumnIndexOrThrow("md5hash")));
				result.add(feeditem);
			} while (cursor.moveToNext());
		}
		cursor.close();
        //dbHelper.close(dbHelper.getDb());
		return result;
	}

	public void insert(String string) {
		// TODO Auto-generated method stub

	}

	public int getIdFromMd5Hash(Context ctx, String md5Hash) {
		dbHelper = DbHelper.getInstance(ctx.getApplicationContext());
		int value = 0;
		Cursor c = dbHelper.getDb().query(dbHelper.DB_TABLE_FEEDITEM, null,
			    "md5hash LIKE '" + md5Hash +"'", null, null, null, null);
		if (c.moveToFirst()) {
			do {
				value = c.getInt(c.getColumnIndex("_id"));
			} while (c.moveToNext());

		}
		c.close();
		return value;
	}

}
